iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
自我挑戰組

前端菜鳥的react初體驗系列 第 22

前端菜鳥的react初體驗 Day22-Hook-useCallback

  • 分享至 

  • xImage
  •  

今天沒有絕望,但是火燒屁股。
https://ithelp.ithome.com.tw/upload/images/20221007/20152660y0TL55PwyS.png

今天要來討論useCallback。

通常討論useCallback,就會順便討論useMemo,
不過今天關於useMemo只會提到這麼一點點,剩下的就是明天(或者後天)的事情了。

useCallback vs useMemo

  • useCallback:回傳一個記憶的function
  • useMemo:回傳一個記憶的值

因此也可以很好的理解react文件的這句話

useCallback(fn, deps) 相等於 useMemo(() => fn, deps)。

他們都是回傳一個記憶的東西,差別在於一個是值還是函式,所以當useMemo變成函式的時候,就跟useCallback一樣了。

useCallback

那麼,為什麼我們需要回傳一個記憶的function呢?直接把function拉出來就好了。

w3school是這麼說的:

One reason to use useCallback is to prevent a component from re-rendering unless its props have changed.

沒錯,就是re-rendering的問題,還記得我前幾天說useState+useEffect有時候會造成無限迴圈,而我覺得基本上是useEffect的鍋嗎?
https://ithelp.ithome.com.tw/upload/images/20221007/20152660K8UdXeivL9.png

所以useCallback的其中一個特點就是,他可以避免re-render的問題。

那麼,該怎麼寫呢?
仔細一看,欸?其實跟uesEffect還滿像的吧?
都會有一個function,也會有一個dependenciesdependencies對function的影響,可以拿useEffect來回味一下。

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

那麼就來寫一個簡單的計數器吧,

const App = () => {
  const [count, setCount] = useState(0);

  const resetCount = useCallback(() => {
       setCount(0);
  }, []);
  
  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount((count) => count + 1)}>Increment</button>
      <button onClick={resetCount}>reset</button>
    </>
  );
};

但事實上,我們會發現,如果我把這個useCallback,改成一般的function,不管對於計數還是重置,都不會有影響。

  const resetCount = useCallback(() => {
       setCount(0);
  }, []);
  const resetCount= () => {
    setCount(0)
  }

那,我們到底會甚麼會需要一個不會觸發re-renderuseCallback呢?

因為今天實在太晚了,所以我們只能,明天來繼續探討為什麼了!
https://ithelp.ithome.com.tw/upload/images/20221007/20152660DSfgSLHsgZ.jpg

參考資料
https://israynotarray.com/react/20220928/3362055744/
https://ithelp.ithome.com.tw/m/articles/10270317


上一篇
前端菜鳥的react初體驗 Day21-Hook-useReducer
下一篇
前端菜鳥的react初體驗 Day23-Hook-useCallback(2)
系列文
前端菜鳥的react初體驗30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言